import {baseUrl, getLoginToken, updateWXInfo} from '../api/index'
import {getUserInfo} from './getUserInfo'
// 检测值类型
const isType = (val, type) => {
  return Object.prototype.toString.call(val).toLowerCase() === '[object ' + type + ']'
}

// 空对象
const isEmptyObject = (obj) => {
  return Object.keys(obj).length === 0 && isType(obj, 'object')
}
const objUrlToParam = (data) => {
  return isEmptyObject(data) ? '' : ('/' + Object.keys(data).map(key => ([key, data[key]].join('/'))).join('/'))
}

// 显示请求错误消息
function showStatusToast (code) {
  let _status = {
    100: '认证通过',
    101: '该帐号已被禁用',
    102: '认证未通过',
    103: '登录凭证过期',
    104: '未获取登录凭证',
  }
  let _title = _status[code]
  if (_title != null) {
    wx.showToast({
      icon: 'none',
      title: _title
    })
  }
}

// 检查是否未登录
function checkIsLogout (token, status) {
  if (!token) {
    return true
  } else {
    return (status === 102 || status === 103 || status === 104)
  }
}

let loginState = null // 是否登录中
let lastFailRequestCfg = []

/**
 * @param resolve promise resolve
 * @param reject promise reject
 * @param config 请求参数
 */
const awaitLoginCallback = (resolve, reject, config) => {
  wx.removeStorageSync('auth_token')
  // 缓存请求，及promise处理函数
  lastFailRequestCfg.push({
    resolve,
    reject,
    config
  })
  // 正在登录时直接返回，由于当前请求promise状态为sending
  if (loginState === 'loading') {
    return
  }
  
  // 重新登录
  // 登录成功后，执行队列请求
  wx.showLoading({
    title: '正在登录...'
  })
  loginState = 'loading'
  _wxLoginRequest((loginData) => {
    loginState = null
    let token = loginData.info.token
    wx.setStorageSync('auth_token', token)
    wx.showLoading({
      icon: 'none',
      title: '请求数据...'
    })
    lastFailRequestCfg.forEach(item => {
      _wxRequest(item.config)
      .then(res => {
        item.resolve(res)
        wx.hideLoading()
      })
      .catch(err => {
        item.reject(err)
        wx.hideLoading()
      })
    })
    console.log(lastFailRequestCfg, 'lastFailRequestCfg')
    // 清空请求队列缓存
    lastFailRequestCfg = []
  }, (err) => {
    reject(err)
  })
}


// wx.login
// 登录过期后重新请求登录接口
// 请求微信登录接口
function _wxLoginRequest (success, fail) {
  wx.login({
    success ({code}) {
      // 发送 res.code 到后台换取 openId, sessionKey, unionId
      let _openid = wx.getStorageSync('shared_openid') || '0'
      getLoginToken(code, _openid, 'isLogin').then((res) => {
        let _data = res.data
        wx.setStorageSync('user_openid', _data.info.openid)
        wx.removeStorageSync('share_openid')
        wx.setStorageSync('auth_token', _data.info.token)
        // wx.showToast({
        //   icon: 'none',
        //   title: '登录成功'
        // })
        // 登录成功后更新用户头像信息
        getUserInfo()
        success && success(_data)
      }).catch(err => {
        console.log(err)
        wx.showToast({
          icon: 'none',
          title: '登录失败，请稍候重试'
        })
        fail && fail(err)
      })
    },
    fail (err) {
      fail && fail(err)
    }
  })
}

// 请求方法
function _wxRequest (opts) {
  console.log('opts', opts)
  let _url = opts.url || ''
  // let __url = baseUrl + _url
  let _headers = {}
  let _token = wx.getStorageSync('auth_token')
  // 转换参数类型
  if (opts.method === 'get' && isType(opts.data, 'object')) {
    _url += objUrlToParam(opts.data)
    opts.data = {}
  }
  let isLoginUrl = opts.data === 'isLogin'
  // 登录接口不需要传递headers token
  if (isLoginUrl) {
    opts.data = {}
  } else {
    _headers = Object.assign({
      'token': _token,
      'positionx': wx.getStorageSync('user_location_x'),
      'positiony': wx.getStorageSync('user_location_y'),
    }, opts.headers)
  }
  
  // 参数预处理
  let _cfg = {
    url: _url.indexOf(baseUrl) === 0 ? _url : baseUrl + _url,
    method: opts.method || 'get',
    data: opts.data || {},
    header: _headers || {}
  }
  
  // 发起网络请求
  return new Promise((resolve, reject) => {
    wx.showNavigationBarLoading()
    wx.request(Object.assign(
      {
        success (res) {
          let _status = res.data.status
          let _info = res.data.info
          if (isLoginUrl) {
            if (_status === 1) {
              resolve(res)
            } else {
              reject(res)
            }
          } else {
            // 需要登录接口请求，检查程序返回结果是否为未登录，或登录过期，数据校验失败
            if (checkIsLogout(_token, _status)) {
              console.log(2)
              // 进入登录流程，函数传参，保存变量
              awaitLoginCallback(resolve, reject, _cfg)
            } else {
              console.log(3)
              if (_status === 1 || _status === 2 ||
                (isType(_info, 'array') && _info.length > 0) ||
                (isType(_info, 'object') && Object.keys(_info).length > 0)
              ) {
                console.log(4, res)
                resolve(res)
              } else {
                console.log(6)
                // 错误消息
                // showStatusToast(_status)
                let _info = res.data.info
                if (isType(_info, 'string') && _info) {
                  wx.showToast({
                    icon: 'none',
                    title: _info
                  })
                } else {
                  showStatusToast(_status)
                }
                reject(res)
              }
            }
          }
          
          wx.hideNavigationBarLoading()
        },
        fail (fail) {
          console.log('fail: errcode', fail)
          wx.showToast({
            icon: 'none',
            title: fail.errMsg
          })
          reject(fail)
          wx.hideNavigationBarLoading()
        }
      }, _cfg
    ))
  })
}

// 请求数据
const _Request = (method = 'get', url = '', data = {}, headers = {}, action) => {
  return new Promise(function (resolve, reject) {
    let _requestCfg = {
      method: method,
      url: url,
      data: data,
      headers: headers,
    }
    // 登录接口不需要token
    console.log(data, 'data === \'isLogin\'')
    if (data === 'isLogin') {
      _wxRequest(_requestCfg).then((res) => {
        loginState = null
        resolve(res)
      }).catch((err) => {
        reject(err)
      })
    } else {
      // 非登录接口如果没有token，先请求登录接口，返回token后台继续当前请求
      if (!wx.getStorageSync('auth_token')) {
        wx.showLoading({
          title: '正在登录...'
        })
        // 未登录登录后再次请求数据
        _wxLoginRequest((loginData) => {
          wx.hideLoading()
          wx.setStorageSync('auth_token', loginData.info.token)
          _wxRequest(_requestCfg).then((res) => {
            resolve(res)
          }).catch((err) => {
            reject(err)
          })
        }, (err) => {
          wx.hideLoading()
          reject(err)
        })
      } else { // 有token直接请求数据
        _wxRequest(_requestCfg).then((res) => {
          resolve(res)
        }).catch((err) => {
          reject(err)
        })
      }
    }
  })
}

_Request.get = (url, data, headers) => {
  return _Request('get', url, data, headers)
}
_Request.post = (url, data, headers) => {
  return _Request('post', url, data, headers)
}

export const request = _Request
